When creating exception/interrupt stack frames for a guest,
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 10 Nov 2005 14:03:33 +0000 (15:03 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 10 Nov 2005 14:03:33 +0000 (15:03 +0100)
set saved eflags.IF to !saved_upcall_mask. This allows the
guest to test interrupts-enabled in the interrupted context
in the same way as when running natively.

Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/arch/xen/i386/kernel/traps.c
linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/traps.c
linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c
xen/arch/x86/domain.c
xen/arch/x86/x86_32/entry.S
xen/arch/x86/x86_64/entry.S
xen/include/public/arch-x86_32.h
xen/include/public/arch-x86_64.h

index f1ef4e21e229c40b2104ecb236c696a0149dc1d5..5ad8d1b273b40a2c879ee136fed090b3191e330e 100644 (file)
@@ -650,7 +650,7 @@ fastcall void do_int3(struct pt_regs *regs, long error_code)
 
 static inline void conditional_sti(struct pt_regs *regs)
 {
-       if ((uint8_t)(regs->xcs >> 16) == 0)
+       if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
                local_irq_enable();
 }
 
index 7f8c79829c068773d78d0f5481637a9977db0845..269003960e54249fdc37fd2332878350935a5115 100644 (file)
@@ -300,9 +300,8 @@ fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code)
        if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
                                        SIGSEGV) == NOTIFY_STOP)
                return;
-
        /* It's safe to allow irq's after cr2 has been saved */
-       if ((uint8_t)(regs->xcs >> 16) == 0)
+       if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
                local_irq_enable();
 
        tsk = current;
index 80ea2d8cf56ac46d4dc54e33832df16792d05172..07a8a35dcc28f83338aff6d8b08bfa8539512347 100644 (file)
@@ -89,7 +89,7 @@ int register_die_notifier(struct notifier_block *nb)
 
 static inline void conditional_sti(struct pt_regs *regs)
 {
-       if ((uint8_t)(regs->cs >> 32) == 0)
+       if (regs->eflags & X86_EFLAGS_IF)
                local_irq_enable();
 }
 
index 54e1eeadcc912a88e3cff11d73b023ab9c26d96e..1c76222721424f8d46e1c88c579ebcaaa55518c1 100644 (file)
@@ -351,7 +351,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
                                        SIGSEGV) == NOTIFY_STOP)
                return;
 
-       if (likely((uint8_t)(regs->cs >> 32) == 0))
+       if (likely(regs->eflags & X86_EFLAGS_IF))
                local_irq_enable();
 
        if (unlikely(page_fault_trace))
index a37643a5d5897d5aa48f87b309544933f55c4869..b20a4accc8df1cf9350d454a367b3c0708f8fb87 100644 (file)
@@ -647,7 +647,7 @@ long do_switch_to_user(void)
 
     regs->rip    = stu.rip;
     regs->cs     = stu.cs | 3; /* force guest privilege */
-    regs->rflags = stu.rflags;
+    regs->rflags = (stu.rflags & ~(EF_IOPL|EF_VM)) | EF_IE;
     regs->rsp    = stu.rsp;
     regs->ss     = stu.ss | 3; /* force guest privilege */
 
index 5712895a65a07630062089f7dcadc7afeed35151..3d93596dc3498aef082235ce583284464840f8e6 100644 (file)
@@ -156,7 +156,7 @@ ENTRY(vmx_asm_vmexit_handler)
          * By this time, all the setups in the VMCS must be complete.
          */
         .if \launch
-        /* VMLUANCH */
+        /* VMLAUNCH */
         .byte 0x0f,0x01,0xc2
         pushf
         call vm_launch_fail
@@ -394,7 +394,12 @@ FLT14:  movl %eax,%gs:(%esi)
         shll $16,%eax                    # Bits 16-23: saved_upcall_mask
         movw UREGS_cs+4(%esp),%ax        # Bits  0-15: CS
 FLT15:  movl %eax,%gs:4(%esi) 
+        test $0x00FF0000,%eax            # Bits 16-23: saved_upcall_mask
+        setz %ch                         # %ch == !saved_upcall_mask
         movl UREGS_eflags+4(%esp),%eax
+        andl $~X86_EFLAGS_IF,%eax
+        shlb $1,%ch                      # Bit 9 (EFLAGS.IF)
+        orb  %ch,%ah                     # Fold EFLAGS.IF into %eax
 FLT16:  movl %eax,%gs:8(%esi)
         test $TBF_EXCEPTION_ERRCODE,%cl
         jz   1f
index 90e485570bfe4d8e70d154eb6809abd83c54fdbc..27af3eb931edb3d7fd04cdb748e690c6f3542aae 100644 (file)
@@ -352,8 +352,6 @@ create_bounce_frame:
 FLT2:   movq  %rax,32(%rsi)             # SS
         movq  UREGS_rsp+8(%rsp),%rax
 FLT3:   movq  %rax,24(%rsi)             # RSP
-        movq  UREGS_eflags+8(%rsp),%rax
-FLT4:   movq  %rax,16(%rsi)             # RFLAGS
         movq  VCPU_vcpu_info(%rbx),%rax
         pushq VCPUINFO_upcall_mask(%rax)
         testb $TBF_INTERRUPT,%cl
@@ -362,7 +360,15 @@ FLT4:   movq  %rax,16(%rsi)             # RFLAGS
         popq  %rax
         shlq  $32,%rax                  # Bits 32-39: saved_upcall_mask
         movw  UREGS_cs+8(%rsp),%ax      # Bits  0-15: CS
-FLT5:   movq  %rax,8(%rsi)              # CS/saved_upcall_mask
+FLT4:   movq  %rax,8(%rsi)              # CS / saved_upcall_mask
+        shrq  $32,%rax
+        testb $0xFF,%al                 # Bits 0-7: saved_upcall_mask
+        setz  %ch                       # %ch == !saved_upcall_mask
+        movq  UREGS_eflags+8(%rsp),%rax
+        andq  $~X86_EFLAGS_IF,%rax
+        shlb  $1,%ch                    # Bit 9 (EFLAGS.IF)
+        orb   %ch,%ah                   # Fold EFLAGS.IF into %eax
+FLT5:   movq  %rax,16(%rsi)             # RFLAGS
         movq  UREGS_rip+8(%rsp),%rax
 FLT6:   movq  %rax,(%rsi)               # RIP
         testb $TBF_EXCEPTION_ERRCODE,%cl
index 7b09dc67a9fd13fc8c9ba4c85c2fcb902fdc63b1..b11c4821188521e554682e02b2d3e9440b0b013f 100644 (file)
@@ -90,7 +90,7 @@ typedef struct cpu_user_regs {
     uint16_t cs;
     uint8_t  saved_upcall_mask;
     uint8_t  _pad0;
-    uint32_t eflags;
+    uint32_t eflags;        /* eflags.IF == !saved_upcall_mask */
     uint32_t esp;
     uint16_t ss, _pad1;
     uint16_t es, _pad2;
index a0ec55ede18abea39801f88d3e91a6a9b36755f4..e53df602eae2fb606d8845a385d70111ccd211ec 100644 (file)
@@ -154,7 +154,7 @@ typedef struct cpu_user_regs {
     uint16_t cs, _pad0[1];
     uint8_t  saved_upcall_mask;
     uint8_t  _pad1[3];
-    __DECL_REG(flags);
+    __DECL_REG(flags);      /* rflags.IF == !saved_upcall_mask */
     __DECL_REG(sp);
     uint16_t ss, _pad2[3];
     uint16_t es, _pad3[3];